#include "MainComponent.h"
#include "NodeBase.h"


NodeBase::NodeBase(const juce::String& labelText)
    : label(labelText)
{
    // 边界左右各扩展connectorRadius，保证连接点完全在组件区域内
    setSize(160, 100);
    // setRepaintsOnMouseActivity(true);

}

void NodeBase::paint(juce::Graphics& g)
{
    float x = 0;
    float y = 0;
    float w = (float)getWidth();
    float h = (float)getHeight();
    // g.fillAll(juce::Colours::white.fromRGB(200, 100, 30));
    juce::Rectangle<float> rect(x, y, w, h);

    // 1. 画节点本体
    g.setColour(juce::Colours::skyblue.withAlpha(alpha));
    g.fillRoundedRectangle(rect, 8.0f);

    // 2. 标题栏
    juce::Rectangle<float> titleBar(x, y, w, title_bar_height);
    juce::Path titleBarPath;
    float r = 8.0f;
    titleBarPath.startNewSubPath(titleBar.getX(), titleBar.getBottom());
    titleBarPath.lineTo(titleBar.getX(), titleBar.getY() + r);
    titleBarPath.quadraticTo(titleBar.getX(), titleBar.getY(), titleBar.getX() + r, titleBar.getY());
    titleBarPath.lineTo(titleBar.getRight() - r, titleBar.getY());
    titleBarPath.quadraticTo(titleBar.getRight(), titleBar.getY(), titleBar.getRight(), titleBar.getY() + r);
    titleBarPath.lineTo(titleBar.getRight(), titleBar.getBottom());
    titleBarPath.closeSubPath();
    g.setColour(juce::Colours::deepskyblue.darker().withAlpha(alpha));
    g.fillPath(titleBarPath);

    // 3. 边框
    g.setColour(selected ? juce::Colours::green.withAlpha(alpha) : juce::Colours::black.withAlpha(alpha));
    float borderThickness = selected ? 4.0f : 2.0f; // 选中时加粗
    g.drawRoundedRectangle(rect, 8.0f, borderThickness);
    // 4. 标题
    g.setColour(juce::Colours::white.withAlpha(alpha));
    g.setFont(juce::Font(16.0f, juce::Font::bold));
    g.drawText(label, titleBar, juce::Justification::centredLeft);
}

void NodeBase::mouseDown(const juce::MouseEvent& e)
{
    // 只允许在标题栏区域内按下左键时才能拖动
    if (e.mods.isLeftButtonDown())
    {
        // float w = (float)getWidth();
        // 标题栏区域
        // juce::Rectangle<float> titleBar(0, 0, w, title_bar_height);
        // if (titleBar.contains(e.position))
        {
            dragOffset = e.getPosition().toFloat() - juce::Point<float>(0, 0);
            toFront(true);
            isDragging = true;
        }
        // else
        // {
        //     isDragging = false;

        //     // 判断鼠标点击的是哪个连接点
        //     int hitConnector = getConnectorAt(e.getPosition().toFloat());
        //     if (hitConnector != -1)
        //     {
        //         if (auto* parent = findParentComponentOfClass<MainComponent>())
        //         {
        //             auto globalPt = getConnector(hitConnector) + getPosition().toFloat();
        //             parent->startConnecting(this, globalPt); // 传递连接点索引
        //         }
        //     }
        // }
    }
}

void NodeBase::mouseDrag(const juce::MouseEvent& e)
{
    // 只有在标题栏按下时才允许拖动
    if (isDragging && e.mods.isLeftButtonDown())
    {
        auto delta = e.getPosition().toFloat() - dragOffset;
        auto newPos = getPosition().toFloat() + delta;
        setTopLeftPosition((int)newPos.x, (int)newPos.y);
        // 通知父组件重绘（确保连线实时刷新）
        if (auto* parent = getParentComponent())
            parent->repaint();
    }
}

void NodeBase::mouseUp(const juce::MouseEvent& e)
{
    (void)e; // 避免未使用参数警告
    isDragging = false;
}

void NodeBase::mouseMove(const juce::MouseEvent& e)
{
    int hoverNow = getConnectorAt(e.getPosition().toFloat());
    if (hoverNow != -1)
    {
        connectorHover = true;
        repaint();
    }
    else
    {
        if(connectorHover == true)
        {
            connectorHover = false;
            repaint();
        }
    }
    // 让 MainComponent 也能收到 mouseMove，保持连线跟随
    if (auto* parent = findParentComponentOfClass<MainComponent>())
        parent->mouseMove(e.getEventRelativeTo(parent));
}

void NodeBase::mouseExit(const juce::MouseEvent& e)
{
    // 鼠标离开该 node
    (void)e;
    connectorHover = false;
    repaint();
}

void NodeBase::resized()
{
    // 获取当前组件的宽度和高度
    int newWidth = getWidth();
    int newHeight = getHeight();

    width = newWidth;
    height = newHeight;

    // 打印大小信息（调试用）
    // DBG("NodeBase resized: Width = " << width << ", Height = " << height);

}

juce::Point<float> NodeBase::getConnector(int idx) const
{
    float w = (float)getWidth();
    float h = (float)getHeight();
    // 0:左 1:上 2:右 3:下
    switch (idx)
    {
        case 0: // 左
            return { 0.0f + connectorRadius, h / 2.0f };
        case 1: // 上
            return { w / 2.0f, 0.0f + connectorRadius };
        case 2: // 右
            return { w - connectorRadius, h / 2.0f };
        case 3: // 下
            return { w / 2.0f, h - connectorRadius };
        default:
            return { 0, 0 };
    }
}

// 新增：判断鼠标在第几个连接点上，返回索引（-1表示不在任何点上）
int NodeBase::getConnectorAt(const juce::Point<float>& mousePos) const
{
    int hitConnector = -1;
    float minDist = 10000.0f;
    for (int i = 0; i < 4; ++i)
    {
        auto pt = getConnector(i);
        float dist = pt.getDistanceFrom(mousePos);
        if (dist < connectorRadius && dist < minDist)
        {
            minDist = dist;
            hitConnector = i;
        }
    }
    return hitConnector;
}